/*
 * Copyright 2016 atnoce.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.atnoce.net;

import com.atnoce.core.SecurityController;
import com.atnoce.util.Cache;
import com.atnoce.util.CommonUtil;
import com.atnoce.util.FileMd5;
import com.atnoce.util.InitContext;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.lang.StringUtils;

/**
 * 基础网络服务
 * @author atnoce.com
 */
public class BasicNetService {
    private static BasicNetService service;
    /**
     * 获取网络服务实例
     * @return 
     */
    public static BasicNetService getInstance(){
        if(service==null){
            service=new BasicNetService();
        }
        return service;
    }
    public Map<String,Object> regCheckColudAccount(String account) throws IOException{
         Map<String,Object> map=new HashMap<>();
        //PostMethod filePost=new PostMethod("http://192.168.0.102:8080/web/account/regAccount.mvc");
        PostMethod filePost=new PostMethod(Cache.proMap.get("BASE_SERVER_ADDR")+"/onepass/colud/reg.mvc");
        StringPart uname=new StringPart("regAccount", account);
        StringPart pass=new StringPart("mainpass",Cache.oc.getMainPass());
	StringPart regType=new StringPart("regType","pc-window7-64bit");
        Part[] parts={uname,pass,regType};
        // 对于MIME类型的请求，httpclient建议全用MulitPartRequestEntity进行包装
	MultipartRequestEntity mre=new MultipartRequestEntity(parts, filePost.getParams());
	filePost.setRequestEntity(mre);
	HttpClient client=new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(CommonUtil.CONNECTION_TIMEOUT);
	int executeMethod = client.executeMethod(filePost);
        if(executeMethod==200){
             byte[] responseBody = filePost.getResponseBody();
            String result=new String(responseBody);
            if(StringUtils.equals(result, "true")){
                map.put("flag", true);
            }else{
                map.put("flag", false);
                map.put("msg", result);
            }
        }else{
            map.put("flag", false);
            map.put("msg", "请求服务器失败!错误代码："+executeMethod);
        }
       
        return map;
    }
    /**
     * 执行同步
     * @param length
     * @param ltime
     * @param md5
     * @return
     * @throws IOException 
     */
    private static String synch(String ltime,String md5,String coludAccount) throws IOException{
         String result="error";
        PostMethod filePost=new PostMethod(Cache.proMap.get("BASE_SERVER_ADDR")+"/onepass/colud/synch.mvc");
        Part[] parts={new StringPart("ltime",ltime),new StringPart("md5",md5),new StringPart("coludAccount",coludAccount)};
        // 对于MIME类型的请求，httpclient建议全用MulitPartRequestEntity进行包装
	MultipartRequestEntity mre=new MultipartRequestEntity(parts, filePost.getParams());
	filePost.setRequestEntity(mre);
	HttpClient client=new HttpClient();
        
        client.getHttpConnectionManager().getParams().setConnectionTimeout(CommonUtil.CONNECTION_TIMEOUT);
        
	int executeMethod = client.executeMethod(filePost);
        if(executeMethod==200){
             byte[] responseBody = filePost.getResponseBody();
            result=new String(responseBody);
        }else{
            result="请求服务器失败!错误代码："+executeMethod;
        }
        return result;
    }
    public  Map<String,Object> synchDowload(String coundAccount){
        Map<String,Object> result=new HashMap<>();
        
        PostMethod filePost=new PostMethod(Cache.proMap.get("BASE_SERVER_ADDR")+"/onepass/colud/dow.mvc");
        Part[] parts={new StringPart("coludAccount",coundAccount)};
        // 对于MIME类型的请求，httpclient建议全用MulitPartRequestEntity进行包装
	MultipartRequestEntity mre=new MultipartRequestEntity(parts, filePost.getParams());
	filePost.setRequestEntity(mre);
	HttpClient client=new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(CommonUtil.CONNECTION_TIMEOUT);
        try{
            int executeMethod = client.executeMethod(filePost);
            //System.out.println("下载请求服务器响应码:"+executeMethod);
            InputStream in=filePost.getResponseBodyAsStream();
            FileOutputStream out=new FileOutputStream(new File("./onepass.db"));
            byte[] b=new byte[1024];
            int len=0;
            while((len=in.read(b))!=-1){
                out.write(b,0,len);
            }
            in.close();
            out.close();
            result.put("flag", true);
        }catch(Exception e){
            result.put("flag", false);
        }finally{
            filePost.releaseConnection();
        }
        //System.out.println("download success!");
        return result;
    }
    private static Map<String,Object> synchUpload(String md5,String time,String coludAccount) throws FileNotFoundException, IOException{
        Map<String,Object> result=new HashMap<>();
        File file=new File(CommonUtil.DEFAULT_DB_PATH);
	PostMethod filePost=new PostMethod(Cache.proMap.get("BASE_SERVER_ADDR")+"/onepass/colud/upload.mvc");
	FilePart fp=new FilePart("db", file);
	StringPart uname=new StringPart("coludAccount", coludAccount);
	StringPart umd5=new StringPart("md5",md5);
        StringPart utime=new StringPart("time",time);
	Part[] parts={uname,umd5,fp,utime};
	// 对于MIME类型的请求，httpclient建议全用MulitPartRequestEntity进行包装
	MultipartRequestEntity mre=new MultipartRequestEntity(parts, filePost.getParams());
	filePost.setRequestEntity(mre);
	HttpClient client=new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(CommonUtil.CONNECTION_TIMEOUT);
	int executeMethod = client.executeMethod(filePost);
	if(executeMethod==200){
            result.put("flag", true);
        }else{
            result.put("flag",false);
            result.put("msg", "同步数据时发生错误："+executeMethod);
        }
        return result;
    }
    public  Map<String,Object> exeSynch() throws  NoSuchAlgorithmException, Exception{
        Map<String,Object> result=new HashMap<>();
      
        String fileMD5 = FileMd5.fileMD5(new File(CommonUtil.DEFAULT_DB_PATH));
        
        if(StringUtils.isBlank(fileMD5)){
            result.put("flag", false);
            result.put("msg", "未计算出数据文件的MD5值！");
            return result;
        }
        String enaccount=SecurityController.getSecurityInstence().decryptColudAccount((String)Cache.proMap.get("coludaccount"));
        //String enaccount = SecurityController.getSecurityInstence().AESdecrypt((String)Cache.proMap.get("coludaccount"),Cache.key);
        String synch = synch((String)Cache.proMap.get("localtime"), fileMD5,enaccount);
        if(StringUtils.equals(synch, "error")){
            result.put("flag", false);
            result.put("msg", "同步服务内部发生错误!");
        }else if(StringUtils.equals(synch, "none")){
            result.put("flag",true);
        }else if(StringUtils.equals(synch, "get")){
            
            //向服务端发送文件
            Map<String, Object> synchUpload = synchUpload(fileMD5, Cache.proMap.get("localtime")+"", enaccount);
            if((boolean)synchUpload.get("flag")){
                result.put("flag", true);
                InitContext.updateProperties("localupdate", "false");
            }else{
                result.put("flag", false);
                result.put("msg", synchUpload.get("msg"));
            }
        }else if(StringUtils.equals(synch, "put")){
            //从服务器端获取文件
            Map<String, Object> synchDowload = synchDowload(enaccount);
            if((boolean)synchDowload.get("flag")){
                result.put("flag", true);
                InitContext.updateProperties("localupdate", "false");
            }else{
                result.put("flag", false);
                result.put("msg", synchDowload.get("msg"));
            }
        }else{
            result.put("flag", false);
            result.put("msg", synch);
        }
        return result;
    }
    public static long getTime() throws MalformedURLException, IOException{
        TimeZone.setDefault(TimeZone.getTimeZone("GMT+8")); // 时区设置 
        URL url=new URL(Cache.proMap.getOrDefault("timeservice", "http://www.qq.com"));//取得资源对象  
	URLConnection uc=url.openConnection();//生成连接对象  
	uc.connect(); //发出连接  
	long ld=uc.getDate(); //取得网站日期时间（时间戳）  
        return ld;
    }
    public String bindColudAccount(String coludAccount) throws IOException{
        String result="error";
        PostMethod filePost=new PostMethod(Cache.proMap.get("BASE_SERVER_ADDR")+"/onepass/colud/bindColudAccount.mvc");
        Part[] parts={new StringPart("coludAccount",coludAccount)};
        // 对于MIME类型的请求，httpclient建议全用MulitPartRequestEntity进行包装
	MultipartRequestEntity mre=new MultipartRequestEntity(parts, filePost.getParams());
	filePost.setRequestEntity(mre);
	HttpClient client=new HttpClient();
        
        client.getHttpConnectionManager().getParams().setConnectionTimeout(CommonUtil.CONNECTION_TIMEOUT);
        
	int executeMethod = client.executeMethod(filePost);
        if(executeMethod==200){
            byte[] responseBody = filePost.getResponseBody();
            result=new String(responseBody);
        }else{
            result="请求服务器失败!错误代码："+executeMethod;
        }
        return result;
    }
}
